﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Silvermoon.OpenGL;
using System.Threading;
using Silvermoon.UI;
using Silvermoon.Shapes;
using Silvermoon.Core;

namespace Silvermoon.Controls.Forms
{
    /// <summary>
    /// Dialog with title, message and ok/cancel button.
    /// </summary>
    public class MessageDialog : Dialog
    {
        private Label message;
        private Label title;
        private DialogButton okBtn, cancelBtn;

        public MessageDialog()
            : base()
        {
            //    SetTransition(500, TransitionMask.Bottom, TransitionMask.Bottom);
            Initialize();
        }

        public MessageDialog(string title, string message)
            : this()
        {
            Title = title;
            Message = message;
        }

        private void Initialize()
        {
            //Margin = new Margin(true, false) { Bottom = 0 };
            Margin = GetMarginFromPlacement(MessageDialogPlacement.Top);
            TextColor = Color.White;
            ModalColor = Color.Black;

            okBtn = new DialogButton
             {
                 Result = DialogResult.OK,
                 Size = new Size(210, 64),
                 Content = "OK",
                 Color = Color.DarkGreen,
             };

            cancelBtn = new DialogButton
             {
                 Result = DialogResult.Cancel,
                 Content = "Cancel",
                 Color = Color.DarkRed,
                 Size = new Size(210, 64),
             };

            title = new Label
            {
                Text = "Dialog",
                Font = FontSprite.Bold,
                Alignment = Alignment.Center,
                Margin = new Margin(20, 20, 20, null),
                Height = 48
            };

            message = new Label
            {
                LineAlignment = Alignment.Near,
                Alignment = Alignment.Center,
                LineMode = LineMode.WordWrap,
                Margin = new Margin(20, 64, 20, 64)
            };
            Controls.Add(title, message, okBtn, cancelBtn);
        }

        public Alignment TitleAlignment
        {
            get { return title.Alignment; }
            set
            {
                title.Alignment = value;
            }
        }

        public Alignment MessageAlignment
        {
            get { return message.Alignment; }
            set
            {
                message.Alignment = value;
            }
        }

        public FontSprite TitleFont
        {
            get { return title.Font; }
            set
            {
                title.Font = value;
                Invalidate(InvalidationFlag.Layout);
            }
        }

        public string Title
        {
            get { return title.Text; }

            set { title.Text = value; }
        }

        public string Message
        {
            get { return message.Text; }
            set
            {
                message.Text = value;
            }
        }

        public Shape OK
        {
            get { return okBtn.Content; }
            set { okBtn.Content = value; }
        }

        public Shape Cancel
        {
            get { return cancelBtn.Content; }
            set { cancelBtn.Content = value; }
        }

        protected override void OnLayout()
        {
            if (CheckFlag(InvalidationFlag.Layout | InvalidationFlag.Size))
            {
                int h = title.Font.CharHeight;
                title.Height = h;
                message.Margin.Top = h + 34;

                int w = Width;
                int top = Height - okBtn.Height - 24;
                int w2 = w / 2;
                okBtn.Location = new Point(w2 - okBtn.Width - 20 / 2, top);
                cancelBtn.Location = new Point(w2 + 20 / 2, top);
            }
            base.OnLayout();
        }

        public override void ShowModal()
        {
            CalculateSize();
            base.ShowModal();
        }

        public override void Show(VisualState showState)
        {
            CalculateSize();
            base.Show(showState);
        }

        private void CalculateSize()
        {
            int sw = Screen.Width - 32;
            int sh = Screen.Height - 32;
            FontSprite font = this.message.Font;
            string message = Message;

            int margin = this.message.Margin.Width;
            IList<string> lines = font.WordWrapLines(message, new Size(sw - margin, sh), 0);
            //this.message.Alignment = lines.Count > 1 ? Alignment.Near : Alignment.Center;
            int th = lines.Count * font.CharHeight;

            int h = Math.Min(sh, th + this.message.Margin.Height + 80);
            Size = new Size(sw, h);
        }

        public static void Show(string title, string message)
        {
            Show(title, message, null, null, MessageDialogPlacement.Top);
        }

        public static void Show(string title, string message, ThreadStart onOk, ThreadStart onCancel)
        {
            Show(title, message, onOk, onCancel, MessageDialogPlacement.Top);
        }

        public static void Show(string title, string message, ThreadStart onOk, ThreadStart onCancel, MessageDialogPlacement placement)
        {
            MessageDialog dlg = new MessageDialog(title, message);
            dlg.Margin = GetMarginFromPlacement(placement);

            dlg.Closed += (s, e) =>
                {
                    dlg.Dispose();
                    switch (e.Result)
                    {
                        case DialogResult.OK:
                            if (onOk != null) onOk();
                            break;

                        case DialogResult.Cancel:
                            if (onCancel != null) onCancel();
                            break;
                    }
                };
            dlg.ShowModal();
        }

        private static Margin GetMarginFromPlacement(MessageDialogPlacement placement)
        {
            switch (placement)
            {
                case MessageDialogPlacement.Centered:
                    return Margin.Centered;

                case MessageDialogPlacement.Top:
                    return new Margin(0, 0, 0, null);

                case MessageDialogPlacement.Bottom:
                    return new Margin(0, null, 0, 0);

                default:
                    throw new NotSupportedException();
            }
        }


        public static void Show(string title, string message, Shape ok, Shape cancel, ThreadStart onOk, ThreadStart onCancel)
        {
            MessageDialog dlg = new MessageDialog(title, message);
            dlg.OK = ok;
            dlg.Cancel = cancel;
            dlg.Closed += (s, e) =>
            {
                switch (e.Result)
                {
                    case DialogResult.OK:
                        if (onOk != null) onOk();
                        break;

                    case DialogResult.Cancel:
                        if (onCancel != null) onCancel();
                        break;
                }
                dlg.Dispose();
            };
            dlg.ShowModal();
        }


    }
}

